﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using ASCOM.DriverAccess;
using ASCOM.DeviceInterface;


namespace InterValometer
{
    class Mount
    {
        Telescope T;
        string ScopeID;

        public Mount()
        {
            // no scope driver loaded
            ScopeID = "";
        }

        public bool Connect()
        {
            // present user with dialog to select scope
            ScopeID = Telescope.Choose("ScopeSim.Telescope");

            // if we actually got a scope ID
            if (ScopeID != "")
            {
                // we're already attached to the driver, so disconnect 
                if (T != null && T.Connected)
                {
                    T.Connected = false;
                    T.Dispose();
                }

                // not attached to the driver, so connect 
                try
                {
                    T = new Telescope(ScopeID);
                    T.Connected = true;
                    this.UpdateLatitude();
                    this.UpdateLongitude();
                }
                catch
                {
                    T.Connected = false;
                }
            }

            return true;
        }

        public bool Disconnect()
        {
            return true;
        }

        public void Close()
        {
            if (T != null && T.Connected)
            {
                T.Connected = false;
                T.Dispose();
            }
        }

        public bool ScopeConnected()
        {
            return T.Connected;
        }

        public void UpdateDeclination()
        {
            int degs = 0, mins = 0;
            double tmp = 0, secs = 0;

            if (T.Connected)
            {
                if (T.Declination < 0)
                {
                    degs = Convert.ToInt16(Math.Ceiling(T.Declination));
                    tmp = (degs - T.Declination) * 60;
                    mins = Convert.ToInt16(Math.Floor(tmp));
                }
                else
                {
                    degs = Convert.ToInt16(Math.Floor(T.Declination));
                    tmp = (T.Declination - degs) * 60;
                    mins = Convert.ToInt16(Math.Floor(tmp));
                }

                secs = (tmp - mins) * 60;

                if (secs > 59.99999)
                {
                    mins += 1;
                    secs = 0;
                }

                if (mins == 60)
                {
                    degs += 1;
                    mins = 0;
                }

                this.DeclinationDegrees = degs;
                this.DeclinationMinutes = mins;
                this.DeclinationSeconds = Convert.ToDecimal(secs);
            }
        }


        public void UpdateRightAscension()
        {
            if (T.Connected)
            {
                int hours = Convert.ToInt16(Math.Floor(T.RightAscension));

                double tmp = (T.RightAscension - hours) * 60;
                int mins = Convert.ToInt16(Math.Floor(tmp));

                double secs = (tmp - mins) * 60;

                this.RightAscensionHours = hours;
                this.RightAscensionMinutes = mins;
                this.RightAscensionSeconds = Convert.ToDecimal(secs);
            }
        }

        public void UpdateLatitude()
        {
            // System.Diagnostics.Debug.WriteLine("Lat: " + T.SiteLatitude.ToString());

            if (T.Connected)
            {
                this.LatitudeDegrees = Convert.ToInt32(Math.Truncate(T.SiteLatitude));
                this.LatitudeMinutes = Convert.ToInt32(Math.Truncate(Math.Abs(T.SiteLatitude - this.LatitudeDegrees) * 60));
                this.LatitudeSeconds = Convert.ToDecimal((Math.Abs(T.SiteLatitude - this.LatitudeDegrees) * 60 - this.LatitudeMinutes) * 60);
            }
        }

        public void UpdateLongitude()
        {
            // System.Diagnostics.Debug.WriteLine("Lon: " + T.SiteLongitude.ToString());

            if (T.Connected)
            {
                this.LongitudeDegrees = Convert.ToInt32(Math.Truncate(T.SiteLongitude));
                this.LongitudeMinutes = Convert.ToInt32(Math.Truncate(Math.Abs(T.SiteLongitude - this.LongitudeDegrees) * 60));
                this.LongitudeSeconds = Convert.ToDecimal((Math.Abs(T.SiteLongitude - this.LongitudeDegrees) * 60 - this.LongitudeMinutes) * 60);
            }
        }

        public int DeclinationDegrees { get; set; }
        public int DeclinationMinutes { get; set; }
        public decimal DeclinationSeconds { get; set; }

        public int RightAscensionHours { get; set; }
        public int RightAscensionMinutes { get; set; }
        public decimal RightAscensionSeconds { get; set; }

        public int LatitudeDegrees { get; set; }
        public int LatitudeMinutes { get; set; }
        public decimal LatitudeSeconds { get; set; }

        public int LongitudeDegrees { get; set; }
        public int LongitudeMinutes { get; set; }
        public decimal LongitudeSeconds { get; set; }
    }
}



/**
 * 



//                /* slew and sync to Polaris for the time being 
//                T.TargetDeclination = 12.2546224594116;
//                T.TargetRightAscension = -16.3872456550598;
//                T.SlewToTarget();
//                T.SyncToTarget();



        private void button3_Click(object sender, EventArgs e)
        {
            if (T != null && T.Connected)
            {
                ScopeDectoUserDec();
                ScopeRAtoUserRA();
            }
            /* This will sync the mounts eq coords with the supplied ones, essentially realigning it
            if (T.Connected)
            {
                if (T.CanSync)
                {
                    T.TargetRightAscension = GetTargetRA();
                    T.TargetDeclination = GetTargetDec();
                    T.SyncToTarget();
                }
            }
             
        }

        private void timer5_Tick(object sender, EventArgs e)
        {
            if (T.Connected)
            {
                double tmp = T.RightAscension;
                int hours = Convert.ToInt16(Math.Floor(tmp));

                tmp = (tmp - hours) * 60;
                int mins = Convert.ToInt16(Math.Floor(tmp));

                double secs = (tmp - mins) * 60;

                numericUpDown16.Value = hours;
                numericUpDown15.Value = mins;
                numericUpDown14.Value = Convert.ToDecimal(secs);

                tmp = T.Declination;
                int degs = 0;

                if (T.Declination < 0)
                {
                    degs = Convert.ToInt16(Math.Ceiling(tmp));
                    tmp = (degs - tmp) * 60;
                    mins = Convert.ToInt16(Math.Floor(tmp));
                }
                else
                {
                    degs = Convert.ToInt16(Math.Floor(tmp));
                    tmp = (tmp - degs) * 60;
                    mins = Convert.ToInt16(Math.Floor(tmp));
                }

                numericUpDown13.Value = degs;
                numericUpDown12.Value = mins;
                numericUpDown11.Value = Convert.ToDecimal((tmp - mins) * 60);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (T != null && T.Connected)
            {
                Console.WriteLine("{0}, {1}", GetTargetRA(), GetTargetDec());
                Console.WriteLine("{0}, {1}", T.RightAscension, T.Declination);
                
                T.TargetRightAscension = GetTargetRA();
                T.TargetDeclination = GetTargetDec();

                if (T.CanSlew)
                {
                    if (!T.Tracking)
                        T.Tracking = true;

                    T.SlewToTargetAsync();
                }
            }
        }

        private void ScopeRAtoUserRA()
        {
            SetTargetRA(T.RightAscension);
        }

        private void ScopeDectoUserDec()
        {
            SetTargetDec(T.Declination);
        }

        private double GetTargetRA()
        {
            return Convert.ToDouble(numericUpDown5.Value + numericUpDown6.Value / 60 + numericUpDown7.Value / 3600);
        }

        private double GetTargetDec()
        {
            double tmpval = 0;

            if (numericUpDown8.Value < 0)
                tmpval = Convert.ToDouble(numericUpDown8.Value - numericUpDown9.Value / 60 - numericUpDown10.Value / 3600);
            else
                tmpval = Convert.ToDouble(numericUpDown8.Value + numericUpDown9.Value / 60 + numericUpDown10.Value / 3600);

            return tmpval;
        }



**/